package com.sjz.rydemo.net;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;


import com.alibaba.fastjson.JSON;
import com.luck.picture.lib.entity.LocalMedia;
import com.sjz.rydemo.base.AppHelper;
import com.sjz.rydemo.utils.LibCollections;
import com.sjz.rydemo.utils.LogUtil;
import com.sjz.rydemo.utils.XYSPUtils;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import cn.rongcloud.rtclib.BuildConfig;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;


/**
 * Created by Administrator on 2016/8/17.
 */
public class HttpUtils {

    private static final MediaType JSON_FORM = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");

    static OkHttpClient sClient = null;
    private static final String TAG = "HttpUtils";

    public synchronized static OkHttpClient getClient() {
        if (sClient == null) {
            sClient = new OkHttpClient.Builder()
                    .connectTimeout(600000, TimeUnit.SECONDS)
                    .readTimeout(600000, TimeUnit.SECONDS)
                    .writeTimeout(600000, TimeUnit.SECONDS)
                    .build();
        }

        return sClient;
    }

    //异步post请求
    public static void getResult(String url, Map<String, Object> params, Callback callBack) {
        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);
        String json = JSON.toJSONString(params);
        Log.e(TAG, "toJSON: " + json);
        RequestBody body = RequestBody.create(json, MEDIA_TYPE);

//        Request request;
//        Request.Builder build = new Request.Builder();
//        if (!TextUtils.isEmpty(head))
//            build.addHeader("Authorization", JLSPUtils.getString(Common.KEY_APP_TOKEN_HEAD) + JLSPUtils.getString(Common.KEY_APP_BEARER_TOKEN));
//        Request request;
        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        Request request = build.url(url).post(body).build();

//        Request request = new Request.Builder()
//                .addHeader("Authorization", TextUtils.isEmpty(head) ? "" : "Bearer " + head)
//                .url(url)
//                .post(body)
//                .build();
        OkHttpClient httpClient = getClient();
        httpClient.newCall(request).enqueue(callBack);

        LogUtil.e("接口链接", "==========" + url + "   Token-->" + head);
        LogUtil.e("传送数据", "==========" + params);
    }


    //异步post请求
    public static void postResult(String url, Map<String, Object> params, Callback callBack) {

        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);

        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, Object>> set = params.entrySet();
        for (Map.Entry<String, Object> entry : set) {
            builder.add(entry.getKey(), entry.getValue().toString());
        }
        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        build.url(url);
        build.post(builder.build());
        OkHttpClient httpClient = getClient();
        httpClient.newCall(build.build()).enqueue(callBack);

        LogUtil.e("接口链接", "==========" + url + "   Token-->" + head);
        LogUtil.e("传送数据", "==========" + params);
    }

    //异步put请求
    public static void putResult(String url, Map<String, Object> params, Callback callBack) {
//        String paramsStr = new JSONObject(params).toString();
//        String paramsStr = new Gson().toJson(params);
        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, Object>> set = params.entrySet();
        for (Map.Entry<String, Object> entry : set) {
            builder.add(entry.getKey(), entry.getValue().toString());
        }
//        FormBody formBody=new FormBody.Builder().add("a","1").add("b","1").build();
//        RequestBody formBody = RequestBody.create(MEDIA_TYPE, paramsStr);
        Request request = new Request.Builder()
                .addHeader("accept", "application/json")
                .url(url)
                .put(builder.build())
                .build();
        OkHttpClient httpClient = getClient();
        httpClient.newCall(request).enqueue(callBack);
        LogUtil.e("接口链接", "==========" + url);
        LogUtil.e("传送数据", "==========" + params);
    }


    //异步delete请求
    public static void delete(String url, Map<String, Object> params, Callback callBack) {
//        String paramsStr = new JSONObject(params).toString();
//        String paramsStr = new Gson().toJson(params);
        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, Object>> set = params.entrySet();
        for (Map.Entry<String, Object> entry : set) {
            builder.add(entry.getKey(), entry.getValue().toString());
        }
//        FormBody formBody=new FormBody.Builder().add("a","1").add("b","1").build();
//        RequestBody formBody = RequestBody.create(MEDIA_TYPE, paramsStr);
        Request request = new Request.Builder()
                .addHeader("accept", "application/json")
                .url(url)
                .delete()
                .build();
        OkHttpClient httpClient = getClient();
        httpClient.newCall(request).enqueue(callBack);
        LogUtil.e("接口链接", "==========" + url);
        LogUtil.e("传送数据", "==========" + params);
    }

    public static void post(String url, Map<String, String> params, TextCallBack callBack) {
        OkHttpClient client = getClient();
        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, String>> set = params.entrySet();
        for (Map.Entry<String, String> entry : set) {
            builder.add(entry.getKey(), entry.getValue());
        }
        Request request = new Request.Builder().url(url).post(builder.build())
                .build();
        LogUtil.e("接口链接", "==========" + url);
        LogUtil.e("传送数据", "==========" + params.toString());
        client.newCall(request).enqueue(callBack);
    }

    public static void postSync(String str) {
//        private static final String ENDPOINT = "https://api.github.com/repos/square/okhttp/contributors";
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder()
                .url(str)
                .build();
        try {
            Response response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void get(String url, TextCallBack callBack) {
        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);
        OkHttpClient client = getClient();
        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        build.url(url);
        client.newCall(build.get().build()).enqueue(callBack);
        LogUtil.e("接口链接", "==========" + url + "   X-Access-Token-->" + head);
    }

    public static void get(String url, Map<String, Object> params, TextCallBack callBack) {
        if (LibCollections.isEmpty(params)) {
            get(url, callBack);
        } else {
            String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);

            OkHttpClient client = getClient();
            Set<Map.Entry<String, Object>> set = params.entrySet();

            boolean isFirst = true;
            for (Map.Entry<String, Object> entry : set) {
                if (isFirst) {
                    url += "?";
                    isFirst = false;
                } else {
                    url += "&";
                }
                url += entry.getKey() + "=" + entry.getValue();
            }

            Request.Builder build = new Request.Builder();
            if (!TextUtils.isEmpty(head))
                build.addHeader("X-Access-Token", head);
            build.url(url);
            client.newCall(build.get().build()).enqueue(callBack);
            LogUtil.e("接口链接", "==========" + url + "   X-Access-Token-->" + head);
            LogUtil.e("传送数据", "==========" + params);
        }

    }

    public static String getSync(String url, Map<String, Object> params) {
        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);

        OkHttpClient client = getClient();
        Set<Map.Entry<String, Object>> set = params.entrySet();

        boolean isFirst = true;
        for (Map.Entry<String, Object> entry : set) {
            if (isFirst) {
                url += "?";
                isFirst = false;
            } else {
                url += "&";
            }
            url += entry.getKey() + "=" + entry.getValue();
        }
        LogUtil.e("接口链接", "==========" + url + "   X-Access-Token-->" + head);
        LogUtil.e("传送数据", "==========" + params);
        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        build.url(url);
//        client.newCall(build.get().build()).enqueue(callBack);
        try {
            Response result = client.newCall(build.get().build()).execute();
            return result.body().string();
        } catch (IOException e) {
            LogUtil.e("响应结果", "==========" + e);
            throw new RuntimeException(e);
        }
    }


    /**
     * @param url        接口
     * @param jsonObject json对象
     * @param callBack
     */
    public static void post(String url, JSONObject jsonObject, TextCallBack callBack) {
        OkHttpClient client = getClient();
        FormBody.Builder builder = new FormBody.Builder();
        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = String.valueOf(keys.next());
            try {
                String value = jsonObject.get(key).toString();
                builder.add(key, value);
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        LogUtil.e("接口链接", "==========" + url);
        LogUtil.e("传送数据", "==========" + jsonObject);
        client.newCall(request).enqueue(callBack);

    }

    public static void postSync(String url, JSONObject jsonObject) {
        OkHttpClient client = getClient();
        Log.e("gouwuche", url + jsonObject);
        FormBody.Builder builder = new FormBody.Builder();
        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = String.valueOf(keys.next());
            try {
                String value = jsonObject.get(key).toString();
                builder.add(key, value);
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        try {
            client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void postVideo(String url, JSONObject jsonObject, TextCallBack callBack) {
        OkHttpClient client = getClient();

        FormBody.Builder builder = new FormBody.Builder();
        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = String.valueOf(keys.next());
            try {
                String value = jsonObject.get(key).toString();
                byte[] bytes = string2bytes(value);
                String byte2String = new String(bytes);
                builder.add(key, byte2String);
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
        Request request = new Request.Builder().url(url)
                .post(builder.build())
                .build();

        client.newCall(request).enqueue(callBack);
    }

    private static byte[] string2bytes(String filePath) {
        if (new File(filePath).exists() && new File(filePath).isFile()) {
            FileInputStream fileInputStream = null;
            byte[] bytes;
            try {
                fileInputStream = new FileInputStream(new File(filePath));
                bytes = new byte[1024];
                int read = 0;
                while ((read = fileInputStream.read()) != -1) {
                    fileInputStream.read(bytes, 0, read);
                }
                return bytes;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            Log.e(TAG, "string2bytes: 文件不存在=========");
        }
        return null;
    }

    public static void postAndFile(Context context, String url, JSONObject jsonObject, File file, TextCallBack callBack) {
        ACache aCache = ACache.get(context);
        if ("0".equals(aCache.getAsString("is_wifi"))) {
            Toast.makeText(context, "没有网络,请连接网络后重试", Toast.LENGTH_SHORT).show();
            return;
        }

        MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (file != null) {
            // MediaType.parse() 里面是上传的文件类型。
            RequestBody body = RequestBody.create(MediaType.parse("image/*"), file);
            // 参数分别为， 请求key ，文件名称 ， RequestBody
            requestBody.addFormDataPart("file", file.getName(), body);
        }
        OkHttpClient client = getClient();
        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = String.valueOf(keys.next());
            try {
                String value = jsonObject.get(key).toString();
//                builder.add(key, value);
                requestBody.addFormDataPart(key, value);
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }

        Request request = new Request.Builder().url(url).post(requestBody.build()).build();
//        eLength("接口链接", "==========" + url);
//        eLength("传送数据", "==========" + jsonObject);
        client.newCall(request).enqueue(callBack);

    }

    public static void upLoadFiles(String url, String uploadParamsName, String aBsolutePaths, String bizPath, OnResultCallBack callBack) {
        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);
        /* 第一个要上传的file */
        /* form的分割线,自己定义 */
        String boundary = "yjkj";
        MultipartBody.Builder mBody = new MultipartBody.Builder(boundary).setType(MultipartBody.FORM);
        //遍历List中的值
        File file = new File(aBsolutePaths);
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
        mBody.addFormDataPart(uploadParamsName, file.getName(), fileBody);
        mBody.addFormDataPart("bizPath", bizPath);
        /* 下边的就和post一样了 */
//        Request request = new Request.Builder().url(url).post(mBody.build()).build();

        LogUtil.e("uploadFile", "fileSize-->" + file.length());
        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        Request request = build.url(url).post(mBody.build()).build();

        OkHttpClient client = new OkHttpClient();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                LogUtil.e("uploadFile", "call--->" + call.toString() + "   IOException-->" + e.toString());
                callBack.OnFailCallBack("####onFailure####");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                callBack.OnResultCallBack(response.body().string());
            }
        });
    }

    public static void upLoadFiles(String url, String uploadParamsName, List<LocalMedia> files, String bizPath, OnResultCallBack callBack) {
        LogUtil.e("响应结果", "==========url-->" + url);
        String head = XYSPUtils.getString(Common.KEY_APP_TOKEN);
        /* 第一个要上传的file */
        /* form的分割线,自己定义 */
        String boundary = "yjkj";
        MultipartBody.Builder mBody = new MultipartBody.Builder(boundary).setType(MultipartBody.FORM);
        //遍历List中的值

        if (BuildConfig.DEBUG && files != null && files.size() == 1) {
            String path = files.get(0).getCompressPath();

            if (TextUtils.isEmpty(path)) {
                path = files.get(0).getRealPath();
            }
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                long length = file.length();
                double real = (double) length / (1024 * 1024);
            }
        }
        for (LocalMedia file : files) {
            mBody.addFormDataPart(uploadParamsName, file.getFileName(), RequestBody.create(MediaType.parse(file.getMimeType()), new File(TextUtils.isEmpty(file.getCompressPath()) ? file.getRealPath() : file.getCompressPath())));
        }

        mBody.addFormDataPart("bizPath", bizPath);
        /* 下边的就和post一样了 */
//        Request request = new Request.Builder().url(url).post(mBody.build()).build();

        Request.Builder build = new Request.Builder();
        if (!TextUtils.isEmpty(head))
            build.addHeader("X-Access-Token", head);
        Request request = build.url(url).post(mBody.build()).build();

        OkHttpClient client = getClient();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                callBack.OnFailCallBack("####onFailure####--->" + e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                callBack.OnResultCallBack(response.body().string());
            }
        });
    }

    /**
     * 下载文件
     *
     * @param url
     * @param saveDir
     * @param downloadListener
     */
    public static void doDownLoadFile(String url, final String saveDir, final DownloadListener downloadListener) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        OkHttpClient httpClient = getClient();

        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                callBack.OnFailCallBack("####onFailure####");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                String saveFolder = isExistDir(saveDir);
                String tempPath = saveFolder + File.separator + "zcjc_" + System.currentTimeMillis() + ".png";
//                String tempPath = saveFolder + File.separator + "zcjc_" + getNameFromUrl(url) + ".png";
//                String savePath = saveFolder + File.separator + getNameFromUrl(url);
                try {
                    AppHelper.delete(tempPath);
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    File file = new File(tempPath);
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中
                        downloadListener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成
//                    FileUtils.fileRename(tempPath, savePath);
                    downloadListener.onDownloadSuccess(tempPath);
                } catch (Exception e) {
                    downloadListener.onDownloadFailed();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

    public static void downLoadVideoFile(String url, final String saveDir, final DownloadListener downloadListener) {

        Request request = new Request.Builder()
                .url(url)
                .build();
        OkHttpClient httpClient = getClient();

        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                callBack.OnFailCallBack("####onFailure####");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    ResponseBody body = response.body();
                    if (body != null) {
                        long totalSize = body.contentLength();
                        InputStream inputStream = body.byteStream();
                        String saveFolder = isExistDir(saveDir);
                        String tempPath = saveFolder + File.separator + "zcjc_" + System.currentTimeMillis() + ".mp4";
                        FileOutputStream outputStream = new FileOutputStream(tempPath);
                        byte[] buffer = new byte[8192];
                        int bytesRead;
                        long totalBytesRead = 0;

                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                            totalBytesRead += bytesRead;

                            // 计算下载进度
                            int progress = (int) ((totalBytesRead * 100) / totalSize);
                            downloadListener.onDownloading(progress);
                            // 更新 UI 显示下载进度（可以使用 Handler 或 EventBus 在 UI 线程更新进度）
                            if (totalBytesRead >= totalSize) {
                                // 下载完成
                                downloadListener.onDownloadSuccess(tempPath);
                            }
                        }

                        outputStream.close();
                        body.close();
                    }
                } else {
                    // 处理请求失败的情况
                    downloadListener.onDownloadFailed();
                }
            }
        });


//        Aria.download(JLApplication.getAppApplicationContext()).register();//注册aria
//        M3U8VodOption option = new M3U8VodOption(); // 创建m3u8点播文件配
//        option.setUseDefConvert(false);//必须设置false，否则不会使用你重写那两个类
//        option.setBandWidthUrlConverter(new M3U8_Converter());
//        option.setVodTsUrlConvert(new TS_Converter());
//        option.generateIndexFile();
//        long taskId = Aria.download(JLApplication.getAppApplicationContext())
//                .load(url)
//                .setFilePath("保存路径", true) // 设置点播文件保存路径,true表示，如果当前目录有文件，则覆盖相同的文件
//                .m3u8VodOption(option)   // 调整下载模式为m3u8点播
//                .create();
    }

    public static String getNameFromUrl(String url) {
        return url.substring(url.lastIndexOf("/") + 1);
    }

    public static String isExistDir(String saveDir) throws IOException {
        // 下载位置
        File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
        if (!downloadFile.mkdirs()) {
            downloadFile.createNewFile();
        }
        String savePath = downloadFile.getAbsolutePath();
        return savePath;
    }

    public interface DownloadListener {
        /**
         * 下载成功
         */
        void onDownloadSuccess(String path);

        /**
         * @param progress 下载进度
         */
        void onDownloading(int progress);

        /**
         * 下载失败
         */
        void onDownloadFailed();
    }

    public interface OnResultCallBack {
        void OnResultCallBack(String s);

        void OnFailCallBack(String s);
    }

    public interface OnUploadFileCallBack {
        void OnResultCallBack(String s);

        void OnFailCallBack(String s);

        void onUploadProgress(int progress);
    }
}
